package com.kexilo.dict.utils;

import com.kexilo.core.common.utils.StringUtils;
import com.kexilo.core.common.utils.spring.SpringUtils;
import com.kexilo.dict.service.DictService;
import com.kexilo.dict.domain.DictData;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 字典工具类 - dict插件版本
 * 作为dict插件的一部分，提供字典相关的工具方法
 * 
 * @author Kexilo
 */
@SuppressWarnings(value = { "unchecked", "rawtypes" })
public class DictUtils {
    
    /**
     * 分隔符
     */
    public static final String SEPARATOR = ",";

    /**
     * 字典缓存前缀
     */
    private static final String DICT_CACHE_PREFIX = "dict:";

    /**
     * 设置字典缓存
     * 
     * @param key 参数键
     * @param dictDatas 字典数据列表
     */
    public static void setDictCache(String key, List<DictData> dictDatas) {
        try {
            RedisTemplate redisTemplate = SpringUtils.getBean(RedisTemplate.class);
            redisTemplate.opsForValue().set(getCacheKey(key), dictDatas);
        } catch (Exception e) {
            // Redis不可用时忽略缓存操作
        }
    }

    /**
     * 获取字典缓存
     * 
     * @param key 参数键
     * @return dictDatas 字典数据列表
     */
    public static List<DictData> getDictCache(String key) {
        try {
            RedisTemplate redisTemplate = SpringUtils.getBean(RedisTemplate.class);
            Object cacheObj = redisTemplate.opsForValue().get(getCacheKey(key));
            if (StringUtils.isNotNull(cacheObj)) {
                return (List<DictData>) cacheObj;
            }
        } catch (Exception e) {
            // Redis不可用时返回null，从数据库获取
        }
        return null;
    }

    /**
     * 根据字典类型查询字典数据
     * 
     * @param dictType 字典类型
     * @return 字典数据集合信息
     */
    public static List<DictData> getDictDataByType(String dictType) {
        List<DictData> dictDatas = getDictCache(dictType);
        if (StringUtils.isNotEmpty(dictDatas)) {
            return dictDatas;
        }
        
        try {
            DictService dictService = SpringUtils.getBean(DictService.class);
            dictDatas = dictService.selectDictDataByType(dictType);
            if (StringUtils.isNotEmpty(dictDatas)) {
                setDictCache(dictType, dictDatas);
                return dictDatas;
            }
        } catch (Exception e) {
            // 如果没有找到DictService实现，返回空列表
            // 这样可以保证插件独立运行
        }
        return null;
    }

    /**
     * 根据字典类型和字典值获取字典标签
     * 
     * @param dictType 字典类型
     * @param dictValue 字典值
     * @return 字典标签
     */
    public static String getDictLabel(String dictType, String dictValue) {
        return getDictLabel(dictType, dictValue, SEPARATOR);
    }

    /**
     * 根据字典类型和字典标签获取字典值
     * 
     * @param dictType 字典类型
     * @param dictLabel 字典标签
     * @return 字典值
     */
    public static String getDictValue(String dictType, String dictLabel) {
        return getDictValue(dictType, dictLabel, SEPARATOR);
    }

    /**
     * 根据字典类型和字典值获取字典标签
     * 
     * @param dictType 字典类型
     * @param dictValue 字典值
     * @param separator 分隔符
     * @return 字典标签
     */
    public static String getDictLabel(String dictType, String dictValue, String separator) {
        StringBuilder propertyString = new StringBuilder();
        List<DictData> datas = getDictDataByType(dictType);

        if (StringUtils.isNotNull(datas)) {
            if (StringUtils.containsAny(dictValue, separator)) {
                for (String value : dictValue.split(separator)) {
                    for (DictData dict : datas) {
                        if (value.trim().equals(dict.getDictValue())) {
                            propertyString.append(dict.getDictLabel()).append(separator);
                            break;
                        }
                    }
                }
            } else {
                for (DictData dict : datas) {
                    if (dictValue.equals(dict.getDictValue())) {
                        return dict.getDictLabel();
                    }
                }
            }
        }
        return StringUtils.stripEnd(propertyString.toString(), separator);
    }

    /**
     * 根据字典类型和字典标签获取字典值
     * 
     * @param dictType 字典类型
     * @param dictLabel 字典标签
     * @param separator 分隔符
     * @return 字典值
     */
    public static String getDictValue(String dictType, String dictLabel, String separator) {
        StringBuilder propertyString = new StringBuilder();
        List<DictData> datas = getDictDataByType(dictType);

        if (StringUtils.isNotEmpty(datas) && StringUtils.containsAny(dictLabel, separator)) {
            for (String label : dictLabel.split(separator)) {
                for (DictData dict : datas) {
                    if (label.trim().equals(dict.getDictLabel())) {
                        propertyString.append(dict.getDictValue()).append(separator);
                        break;
                    }
                }
            }
        } else if (StringUtils.isNotEmpty(datas)) {
            for (DictData dict : datas) {
                if (dictLabel.equals(dict.getDictLabel())) {
                    return dict.getDictValue();
                }
            }
        }
        return StringUtils.stripEnd(propertyString.toString(), separator);
    }

    /**
     * 根据字典类型获取所有可用的字典值列表
     * 
     * @param dictType 字典类型
     * @return 字典值列表
     */
    public static List<String> getDictValues(String dictType) {
        List<DictData> datas = getDictDataByType(dictType);
        if (StringUtils.isNotEmpty(datas)) {
            return datas.stream()
                    .filter(dict -> "0".equals(dict.getStatus())) // 只返回状态正常的
                    .map(DictData::getDictValue)
                    .collect(Collectors.toList());
        }
        return java.util.Collections.emptyList();
    }

    /**
     * 根据字典类型获取所有可用的字典标签列表
     * 
     * @param dictType 字典类型
     * @return 字典标签列表
     */
    public static List<String> getDictLabels(String dictType) {
        List<DictData> datas = getDictDataByType(dictType);
        if (StringUtils.isNotEmpty(datas)) {
            return datas.stream()
                    .filter(dict -> "0".equals(dict.getStatus())) // 只返回状态正常的
                    .map(DictData::getDictLabel)
                    .collect(Collectors.toList());
        }
        return java.util.Collections.emptyList();
    }

    /**
     * 检查字典值是否有效
     * 
     * @param dictType 字典类型
     * @param dictValue 字典值
     * @return 是否有效
     */
    public static boolean isValidDictValue(String dictType, String dictValue) {
        List<String> validValues = getDictValues(dictType);
        return validValues.contains(dictValue);
    }

    /**
     * 删除指定字典缓存
     * 
     * @param key 字典键
     */
    public static void removeDictCache(String key) {
        try {
            RedisTemplate redisTemplate = SpringUtils.getBean(RedisTemplate.class);
            redisTemplate.delete(getCacheKey(key));
        } catch (Exception e) {
            // Redis不可用时忽略缓存操作
        }
    }

    /**
     * 清空字典缓存
     */
    public static void clearDictCache() {
        try {
            RedisTemplate redisTemplate = SpringUtils.getBean(RedisTemplate.class);
            Collection<String> keys = redisTemplate.keys(DICT_CACHE_PREFIX + "*");
            if (StringUtils.isNotEmpty(keys)) {
                redisTemplate.delete(keys);
            }
        } catch (Exception e) {
            // Redis不可用时忽略缓存操作
        }
    }

    /**
     * 刷新指定字典类型的缓存
     * 
     * @param dictType 字典类型
     */
    public static void refreshDictCache(String dictType) {
        removeDictCache(dictType);
        getDictDataByType(dictType); // 重新从数据库加载
    }

    /**
     * 批量刷新字典缓存
     * 
     * @param dictTypes 字典类型列表
     */
    public static void refreshDictCache(List<String> dictTypes) {
        if (StringUtils.isNotEmpty(dictTypes)) {
            dictTypes.forEach(DictUtils::refreshDictCache);
        }
    }

    /**
     * 获取cache key
     * 
     * @param configKey 参数键
     * @return 缓存键key
     */
    public static String getCacheKey(String configKey) {
        return DICT_CACHE_PREFIX + configKey;
    }

    /**
     * 预热字典缓存
     * 
     * @param dictType 字典类型
     */
    public static void warmupDictCache(String dictType) {
        try {
            DictService dictService = SpringUtils.getBean(DictService.class);
            List<DictData> dictDatas = dictService.selectDictDataByType(dictType);
            if (StringUtils.isNotEmpty(dictDatas)) {
                setDictCache(dictType, dictDatas);
            }
        } catch (Exception e) {
            // 预热失败不影响正常功能
        }
    }

    /**
     * 批量预热字典缓存
     * 
     * @param dictTypes 字典类型列表
     */
    public static void warmupDictCache(List<String> dictTypes) {
        if (StringUtils.isNotEmpty(dictTypes)) {
            dictTypes.forEach(DictUtils::warmupDictCache);
        }
    }
}
